package service

import (
	"fmt"
	"go.uber.org/zap"
	"iot-base/common/cache"
	"iot-base/common/ctrltype"
	"iot-base/common/logger"
	"iot-base/common/notify"
	"regexp"
	"strconv"
	"strings"
	"time"

	"errors"
)

type PM struct {
}

type PMLogic struct {
}

func NewPMLogic() *PMLogic {
	return &PMLogic{}
}

func (this *PMLogic) PM(id string, thing *cache.ThingInfo, v interface{}, round int64) (interface{}, error) {
	ip := thing.GetThingParam("ip", "")
	port := thing.GetThingParam("port", "")
	fpmchr, err := SynHub.SendStrData(ip+":"+port, "fpmchr$")
	if err != nil {
		logger.Log.Error("Calo service.SynHub.SendStrData err:", zap.Error(err))
		return nil, err
	}
	if strings.Contains(fpmchr, "error") {
		logger.Log.Error("PM service.SynHub.SendStrData err:" + fpmchr)
		return nil, err
	}
	logger.Log.Info("PM " + fpmchr)
	fmt.Println("PM info:=", fpmchr, err)
	fpmArr := strings.Split(fpmchr, "=")
	var status float64 = 1
	switch fpmArr[0][0:1] {
	case "*":
		status = 2
	case "#":
		status = 3
	case "!":
		status = 4
	case "%":
		status = 5
	}
	reg := regexp.MustCompile("[\\-]?[\\d]+\\.?[\\d]+")
	data := reg.Find([]byte(fpmArr[1]))
	now := time.Now().Unix()
	pm, _ := strconv.ParseFloat(string(data), 64)
	notify.RawData(thing.Thing.UID, "pm", "", 0, pm, now, now)
	notify.RawData(thing.Thing.UID, "status", "", 0, status, now, now)
	if thing.Thing.ModelID == "m_pm25" {
		notify.RawData(thing.Thing.UID, "pm2.5ValueStatus", "", 0, fmt.Sprintf("%s%v", fpmArr[0][0:1], pm), now, now)
	}
	if thing.Thing.ModelID == "m_pm10" {
		notify.RawData(thing.Thing.UID, "pm10ValueStatus", "", 0, fmt.Sprintf("%s%v", fpmArr[0][0:1], pm), now, now)
	}
	//190548,PM2.5,0.0,0.0,2545.5,99.7,0.00,-34.2,36.7,0.00000,0,40.0,-64.9,39.1,0.00,34.2,2816,33389.0,0.0,0.0,0.0,13673,08,0.00,0.00,39.00,0.0$
	// 获取状态.
	fpmtwc, err := SynHub.SendStrData(ip+":"+port, "fpmtwc$")
	fmt.Println("fpmtwc", fpmtwc, err)
	if err != nil {
		logger.Log.Error("PM service.SynHub.SendStrData err:", zap.Error(err))
		return nil, err
	}
	logger.Log.Info("fpmtwc:" + fpmtwc)
	if strings.Contains(fpmtwc, "error") {
		logger.Log.Error("PM fpmtwc$ service.SynHub.SendStrData err:" + fpmtwc)
		return nil, err
	}
	fpmtwc = fpmtwc[:len(fpmtwc)-1]
	fpmtwcArr := strings.Split(fpmtwc, ",")
	fpmtwcArr = fpmtwcArr[2:]
	// 上报数据.
	ReportDataFloat64(thing.Thing.UID, fpmtwcArr, PMField)
	return nil, nil
}

func (this *PMLogic) PMSv(pCmd *ctrltype.CtrlCmd, tingInfo *cache.ThingInfo) (map[string]interface{}, error) {
	ip := tingInfo.GetThingParam("ip", "")
	port := tingInfo.GetThingParam("port", "")
	var requestMap map[string]interface{}
	requestMap = make(map[string]interface{})
	switch pCmd.ID {
	case "minhis":
		start, ok := pCmd.Params["start"].(string)
		if !ok {
			return nil, errors.New("start type is err")
		}
		end, ok := pCmd.Params["end"].(string)
		if !ok {
			return nil, errors.New("end type is err")
		}
		readbuffer, err := SynHub.SendStrData(ip+":"+port, "fpmhi1="+start+" "+end+"$")
		if err != nil {
			return nil, errors.New("read err:" + err.Error())
		}
		if strings.Contains(readbuffer, "error") {
			logger.Log.Error("pm service.SynHub.SendStrData err:" + readbuffer)
			fmt.Println("pmhis", readbuffer)
			return nil, err
		}
		requestMap["result"] = readbuffer
		return requestMap, nil
	case "hourhis":
		start, ok := pCmd.Params["start"].(string)
		if !ok {
			return nil, errors.New("start type is err")
		}
		end, ok := pCmd.Params["end"].(string)
		if !ok {
			return nil, errors.New("end type is err")
		}
		readbuffer, err := SynHub.SendStrData(ip+":"+port, "fpmhi3="+start+" "+end+"$")
		if err != nil {
			return nil, errors.New("read err:" + err.Error())
		}
		if strings.Contains(readbuffer, "error") {
			logger.Log.Error("pm service.SynHub.SendStrData err:" + readbuffer)
			fmt.Println("pmhis", readbuffer)
			return nil, err
		}
		requestMap["result"] = readbuffer
		return requestMap, nil
	default:
		return nil, errors.New("no service")
	}
}

// PMField 上传字段
var PMField = map[int]string{
	1:  "realtime",
	2:  "allrealtime",
	3:  "power",
	4:  "apress",
	5:  "sflow",
	6:  "heatertemp",
	7:  "boxtemp",
	8:  "dpress",
	9:  "ppress",
	10: "cumulative_mass",
	11: "ambient_temp",
	12: "humidity",
	13: "oflow",
	14: "temp",
}
